/*
* Copyright (c) 2011, 9nali.com All rights reserved.
*/
package com.waitingsnow.core.service
{

import com.waitingsnow.core.debug.Logger;

import flash.events.AsyncErrorEvent;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.NetStatusEvent;
import flash.events.SecurityErrorEvent;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.ObjectEncoding;
import flash.utils.clearTimeout;

[Event(name="connect", type="flash.events.Event")]

[Event(name="close", type="flash.events.Event")]

/**
 * 维护视频连接类
 */
public class NetConnectionService extends EventDispatcher
{
	//==========================================================================
	//  Properties
	//==========================================================================
	private var _connection:NetConnection;
	/**
	 * fms连接
	 */
	public function get connection():NetConnection
	{
		return _connection;
	}
	
	/**
	 * 连接地址
	 */
	public function get connectionUrl():String
	{
		return _connection.uri;
	}
	
	/**
	 * 是否连接
	 */
	public function get connected():Boolean
	{
		return _connection && _connection.connected;
	}
	
	//==========================================================================
	//  Methods
	//==========================================================================
	/**
	 * 开始视频连接
	 * @param url
	 * @param arg
	 */
	public function startConn(url:String, ...arg):void
	{
		if (!_connection)
		{
			_connection = new NetConnection();
			_connection.addEventListener(NetStatusEvent.NET_STATUS, netConnectionHandler);
			_connection.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
			_connection.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler);
			_connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
			_connection.objectEncoding = ObjectEncoding.AMF3;
			_connection.client = new FMSCallDelegate();
		}
		arg.unshift(url);
		_connection.connect.apply(null, arg);
	}
	
	public function dispose():void
	{
		if(_connection)
		{
			_connection.removeEventListener(NetStatusEvent.NET_STATUS, netConnectionHandler);
			_connection.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
			_connection.removeEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler);
			_connection.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
			_connection.close();
			_connection = null;
		}
	}
	
	private function connectSuccess():void
	{
		dispatchEvent(new Event(Event.CONNECT));
	}
	
	private function connectClose():void
	{
		dispatchEvent(new Event(Event.CLOSE));
	}
	
	//==========================================================================
	//  Event Handlers
	//==========================================================================
	/**
	 * 连接状态
	 */
	private function netConnectionHandler(event:NetStatusEvent):void
	{
		Logger.log("event.info.code: " + event.info.code);
		switch (event.info.code)
		{
			case "NetConnection.Connect.Success":
			{
				Logger.log("成功连接FMS服务器！");
				connectSuccess();
				//检查带宽情况
				//connection.call("checkBandwidth", null);
				break;
			}
			case "NetConnection.Connect.Closed":
			{
				connectClose();
				Logger.log("与FMS的连接中断！");
				break;
			}
			case "NetConnection.Connect.Failed":
			{
				connectClose();
				Logger.log("连接失败！");
				break;
			}
			case "NetConnection.Connect.Rejected":
			{
				connectClose();
				Logger.log("遭到服务器拒绝");
				break;
			}
			case "NetConnection.Connect.InvalidApp":
			{
				connectClose();
				Logger.log("指定的应用程序名称没有找到");
				break;
			}
			case "NetConnection.Connect.AppShutDown":
			{
				connectClose();
				Logger.log("服务器端应用程序已经关闭" +
					"(由于资源耗用过大等原因)或者服务器已经关闭！");
				break;
			}
		}
	}
	
	private function errorHandler(event:Event):void
	{
		//有返回则断开时间间隔侦听
		connectClose();
		Logger.log("Fms连接错误： " + event.toString());
	}
}
}


dynamic class FMSCallDelegate extends Object
{
	public function onBWDone(...arg):void
	{
		var bw:Number = 0;
		if(arg.length > 0)
		{
			bw = arg[0];
		}
		if(bw < 15 * 8)
		{
			/*Tracking.action("naliBWLow");*/
		}
	}
	
	public function onBWCheck(...arg):Number
	{
		return 0;
	}
	
	public function onBWClose(...arg):void
	{
	}
}
